package com.scs.application.core.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.entity.TreeEntity;
import com.scs.application.core.mapper.IBaseMapper;
import com.scs.application.core.utils.StringUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 树形service，增强普通service
 */
public class TreeServiceImpl<M extends IBaseMapper<T>, T extends TreeEntity> extends BaseServiceImpl<M, T> implements ITreeService<T> {

    protected void preSave(T entity) {

        if (!entity.isNewRecord()) {
            return;
        }

        String nodeKey = "";
        String parentId = StringUtils.defaultIfBlank(entity.getParentId(), "0");

        List<Object> nodeKeys = this.baseMapper.selectObjs(Wrappers.<T>query()
                .select("max(node_key)").eq("parent_id", parentId)
        );
        String maxChildCode = nodeKeys.get(0) != null ? nodeKeys.get(0).toString() : null;

        if (maxChildCode != null) {
            String parentCode = maxChildCode.substring(0, maxChildCode.length() - 3);
            String subCode = maxChildCode.substring(maxChildCode.length() - 3);
            int sn = Integer.parseInt(subCode) + 1;
            nodeKey = parentCode + String.format("%03d", sn);
        } else {
            T parent = baseMapper.selectById(parentId);
            if (parent != null) {
                nodeKey = StringUtils.defaultString(parent.getNodeKey()) + "001";
            } else {
                nodeKey = "001";
            }
        }
        entity.setNodeKey(nodeKey);
    }

    @Override
    public boolean saveOrUpdate(T entity) {
        preSave(entity);

        boolean success = super.saveOrUpdate(entity);

        // 更新父级 下级数量 字段
        int childCount = this.count(Wrappers.<T>query().eq("parent_id", entity.getParentId()));
        update(Wrappers.<T>update().set("child_count", childCount).eq("id", entity.getParentId()));

        return success;
    }

    @Override
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {

        if (CollectionUtils.isEmpty(idList)) {
            return false;
        }

        Collection<T> entityList = listByIds(idList);

        List<String> nodeKeys = entityList.stream()
                .filter(o -> StringUtils.isNotBlank(o.getNodeKey()))
                .map(o -> o.getNodeKey()).collect(Collectors.toList());

        QueryWrapper<T> entityWrapper = Wrappers.<T>query();
        for (Serializable nodeKey : nodeKeys) {
            // 删除子级节点
            super.remove(entityWrapper.likeRight("node_key", nodeKey));
        }

        // 删除子级节点
        List<String> ids = entityList.stream()
                .filter(o -> StringUtils.isNotBlank(o.getNodeKey()))
                .map(o -> o.getId()).collect(Collectors.toList());
        if (!ids.isEmpty()) {
            super.remove(entityWrapper.in("parent_id", ids));
        }

        for (T t : entityList) {
            int childCount = this.count(Wrappers.<T>query().eq("parent_id", t.getParentId()));
            update(Wrappers.<T>update().set("child_count", childCount).eq("id", t.getParentId()));
        }
        return true;
    }


}
